package com.xyu.gulimall.ware.service.impl;

import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.xyu.common.constant.PurchaseConstant;
import com.xyu.common.constant.WareConstant;
import com.xyu.common.utils.R;
import com.xyu.gulimall.ware.dao.PurchaseDetailDao;
import com.xyu.gulimall.ware.entity.PurchaseDetailEntity;
import com.xyu.gulimall.ware.entity.WareSkuEntity;
import com.xyu.gulimall.ware.feign.ProductFeign;
import com.xyu.gulimall.ware.service.PurchaseDetailService;
import com.xyu.gulimall.ware.service.WareSkuService;
import com.xyu.gulimall.ware.vo.MergeVo;
import com.xyu.gulimall.ware.vo.PurchaseDoneVo;
import com.xyu.gulimall.ware.vo.PurchaseItemsVo;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicReference;
import java.util.stream.Collectors;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xyu.common.utils.PageUtils;
import com.xyu.common.utils.Query;

import com.xyu.gulimall.ware.dao.PurchaseDao;
import com.xyu.gulimall.ware.entity.PurchaseEntity;
import com.xyu.gulimall.ware.service.PurchaseService;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;


@Service("purchaseService")
public class PurchaseServiceImpl extends ServiceImpl<PurchaseDao, PurchaseEntity> implements PurchaseService {

    @Resource
    private PurchaseDetailService purchaseDetailService;
    @Resource
    private PurchaseDetailDao purchaseDetailDao;
    @Resource
    private ProductFeign productFeign;
    @Resource
    private WareSkuService wareSkuService;

    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        IPage<PurchaseEntity> page = this.page(
                new Query<PurchaseEntity>().getPage(params),
                new QueryWrapper<PurchaseEntity>()
        );

        return new PageUtils(page);
    }

    /**
     * 查询未领取的采购单
     *
     * @param params
     * @return
     */
    @Override
    public PageUtils queryPageUnreceivePurchase(Map<String, Object> params) {
        QueryWrapper<PurchaseEntity> wrapper = new QueryWrapper<>();
        //状态封装为枚举
        wrapper.in("status", PurchaseConstant.STATUS_ZONE.getCode(), PurchaseConstant.STATUS_ONE.getCode());
        IPage<PurchaseEntity> page = this.page(new Query<PurchaseEntity>().getPage(params), wrapper);
        return new PageUtils(page);
    }

    /**
     * 合并采购单
     *
     * @param mergeVo 分析有两种清空
     *                一 根据指定采购人员进行合并
     *                二 如果没有指定采购人员自动创建一个
     */
    @Override
    public void mergePurchase(MergeVo mergeVo) {
        //获取采购单id
        Long purchaseId = mergeVo.getPurchaseId();
        //创建采购人员类
        PurchaseEntity purchaseEntity = new PurchaseEntity();
        ;
        purchaseEntity.setId(purchaseId);
        if (purchaseId == null) {
            //新建采购员
            purchaseEntity.setStatus(WareConstant.Purchase.CREATED.getCode());
            this.save(purchaseEntity);
            //创建完成获取当前采购的id 然后合并采购
            purchaseId = purchaseEntity.getId();
            //添加创建时间
            purchaseEntity.setCreateTime(new Date());
            //添加更新时间
            purchaseEntity.setUpdateTime(new Date());
        }
        List<Long> items = mergeVo.getItems();
        Long finalPurchaseId = purchaseId;
        List<PurchaseDetailEntity> collect = items.stream().map((i) -> {
            PurchaseDetailEntity purchaseDetailEntity = new PurchaseDetailEntity();
            //获取当前采购合并的id
            purchaseDetailEntity.setId(i);
            //获取当前合并采购人员
            purchaseDetailEntity.setPurchaseId(finalPurchaseId);
            purchaseDetailEntity.setStatus(WareConstant.PurchaseDetail.ASSIGEND.getCode());
            return purchaseDetailEntity;
        }).collect(Collectors.toList());
        purchaseDetailService.updateBatchById(collect);
        //更新时间
        purchaseEntity.setUpdateTime(new Date());
        this.updateById(purchaseEntity);
    }

    /**
     * 领取采购单
     *
     * @param ids
     */
    @Transactional
    @Override
    public void receivedPurchase(List<Long> ids) {
        //1，确认当前采购单的状态是新建还是已分配
        //遍历到list集合类型为PurchaseEntity中
        List<PurchaseEntity> collect = ids.stream().map((id) -> {
            PurchaseEntity purchaseEntity = new PurchaseEntity();
            purchaseEntity.setId(id);
            return purchaseEntity;
        }).collect(Collectors.toList());

        //查询出符合条件状态为新建和已经分配的
        List<PurchaseEntity> received = baseMapper.received(collect);
        received.forEach(System.out::println);
        //2，改变采购单的状态
        int result = baseMapper.receivedStatus(received, new Date());
        if (result > 0) {
            System.out.println("状态更新成功");
        }
        //3，改变采购项的状态
        result = purchaseDetailDao.updateReceived(received);
        if (result > 0) {
            System.out.println("状态更新成功");
        }
    }

    /**
     * 完成采购操作
     *接收的参数
     * @param doneVo id: 123,//采购单id
     *               items: [{itemId:1,status:4,reason:""}]//完成/失败的需求详情
     *
     */
    @Transactional
    @Override
    public void PurchaseDone(PurchaseDoneVo doneVo) {
        //判断所以采购单的状态，如果有异常结束判断，然后直接修改采购单的状态为3
        //获取所以采购单
        System.out.println(doneVo.toString());
        List<PurchaseItemsVo> purchaseItemsVos = doneVo.getItems();
        AtomicReference<Boolean> flag = new AtomicReference<>(true);
        //获取采购商品的信息
        List<PurchaseDetailEntity> collect = purchaseItemsVos.stream().map((item) -> {
            PurchaseDetailEntity purchaseDetailEntity = new PurchaseDetailEntity();
            //采购单的id
            purchaseDetailEntity.setPurchaseId(doneVo.getId());
            //采购项id
            purchaseDetailEntity.setId(item.getItemId());
            //描述信息
            purchaseDetailEntity.setReason(item.getReason());
            //如果采购商品中有异常说明，则采购单为异常
            //2，改变采购项的状态
            if (item.getStatus() == WareConstant.PurchaseDetail.HASERROR.getCode()) {
                flag.set(false);
                purchaseDetailEntity.setStatus(item.getStatus());
                purchaseDetailService.update(purchaseDetailEntity,new UpdateWrapper<PurchaseDetailEntity>().eq("id",purchaseDetailEntity.getId()));
            } else {
                purchaseDetailEntity.setStatus(item.getStatus());
                purchaseDetailService.update(purchaseDetailEntity,new UpdateWrapper<PurchaseDetailEntity>().eq("id",purchaseDetailEntity.getId()));
            }
            return purchaseDetailEntity;
        }).collect(Collectors.toList());
        //1，改变采购单的状态 //更具flag修改采购单
        PurchaseEntity purchaseEntity = new PurchaseEntity();
        purchaseEntity.setUpdateTime(new Date());
        if(flag.get()){
            purchaseEntity.setStatus(WareConstant.Purchase.FINSHED.getCode());
            //更新完成
            this.update(purchaseEntity,new UpdateWrapper<PurchaseEntity>().eq("id",doneVo.getId()));
        }else {
            //否则有异常更新
            purchaseEntity.setStatus(WareConstant.Purchase.HASERROR.getCode());
            this.update(purchaseEntity,new UpdateWrapper<PurchaseEntity>().eq("id",doneVo.getId()));
        }

        //3，将采购成功的进行入库
        //查询出采购商品 获取sku_id
        List<PurchaseDetailEntity> purchaseDetailEntities = purchaseDetailDao.SelectBatch(collect);
        //获取入库内容
        List<WareSkuEntity> wareSku = purchaseDetailEntities.stream().map((item) -> {
            WareSkuEntity wareSkuEntity = new WareSkuEntity();
            //获取sku_id
            wareSkuEntity.setSkuId(item.getSkuId());
            //获取入库数量
            wareSkuEntity.setStock(item.getSkuNum());
            //获取仓库id
            wareSkuEntity.setWareId(item.getWareId());
            //锁定库存
            wareSkuEntity.setStockLocked(0);
            //远程获取对应sku_id的skuName
            //远程查询sku
            R info = productFeign.info(item.getSkuId());
            Map<String,Object> data = (Map<String,Object>)info.get("skuInfo");
            wareSkuEntity.setSkuName((String) data.get("skuName"));
            return wareSkuEntity;
        }).collect(Collectors.toList());
        //入库
        //查询是否有库存如果有进行添加，没有则创建
        int result = wareSkuService.UpdateBatchDone(wareSku);
        System.out.println("更新成功");
    }

    /**
     * 完成采购 两种方法
     * @param doneVo
     */
    @Transactional
    @Override
    public void done(PurchaseDoneVo doneVo) {

        Long id = doneVo.getId();
        //2、改变采购项的状态
        Boolean flag = true;
        List<PurchaseItemsVo> items = doneVo.getItems();

        List<PurchaseDetailEntity> updates = new ArrayList<>();
        for (PurchaseItemsVo item : items) {
            PurchaseDetailEntity detailEntity = new PurchaseDetailEntity();
            if(item.getStatus() == WareConstant.PurchaseDetail.HASERROR.getCode()){
                flag = false;
                detailEntity.setStatus(item.getStatus());
            }else{
                detailEntity.setStatus(WareConstant.PurchaseDetail.FINSHED.getCode());
                ////3、将成功采购的进行入库
                PurchaseDetailEntity entity = purchaseDetailService.getById(item.getItemId());
                wareSkuService.addStock(entity.getSkuId(),entity.getWareId(),entity.getSkuNum());

            }
            detailEntity.setId(item.getItemId());
            updates.add(detailEntity);
        }

        purchaseDetailService.updateBatchById(updates);

        //1、改变采购单状态
        PurchaseEntity purchaseEntity = new PurchaseEntity();
        purchaseEntity.setId(id);
        purchaseEntity.setStatus(flag?WareConstant.PurchaseDetail.FINSHED.getCode():WareConstant.PurchaseDetail.HASERROR.getCode());
        purchaseEntity.setUpdateTime(new Date());
        this.updateById(purchaseEntity);

    }
}
